<!-- <template>
  <div style="width:100%;height:100%;position:relative;" v-if="isflowRate">
    <template v-if="!playerHidden">
      <div class="live-warp" v-if="playType == '05'">
        <img
          class="img"
          :id="'imgeVideo' + this.options.number"
          :src="playSrc"
          alt=""
          @load="onImgLoad"
        />
      </div>
      <div class="live-warp" v-else>
        <video class="video-js vjs-default-skin" ref="liveVideo"></video>
      </div>
    </template>
    <div class="video-status" v-if="loading">{{ loadingText }}</div>
  </div>
  <div class="nodata" v-else>{{ errorInfo }}</div>
</template>

<script>
import "video.js/dist/video-js.css";
import videojs from "video.js";
import "videojs-flash";
import "videojs-contrib-hls";
import "videojs-flvjs-es6";
import { formatDate } from "@/assets/js/utils";
import { mapState } from "vuex";

// pollfill
if (typeof Object.assign != "function") {
  Object.defineProperty(Object, "assign", {
    value(target, varArgs) {
      if (target == null) {
        throw new TypeError("Cannot convert undefined or null to object");
      }
      const to = Object(target);
      for (let index = 1; index < arguments.length; index++) {
        const nextSource = arguments[index];
        if (nextSource != null) {
          for (const nextKey in nextSource) {
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true,
  });
}
// as of videojs 6.6.0
const DEFAULT_EVENTS = [
  "loadstart",
  "progress",
  "timeupdate",
  "progress",
  "loadedmetadata",
  "loadeddata",
  "canplay",
  "canplaythrough",
  "play",
  "pause",
  "waiting",
  "playing",
  "ended",
  "error",
  "stalled",
];
export default {
  components: {},
  props: {
    initRender: {
      type: Boolean,
      default: false,
    },
    crossOrigin: {
      type: String,
      default: "",
    },
    playsinline: {
      type: Boolean,
      default: false,
    },
    customEventName: {
      type: String,
      default: "statechanged",
    },
    events: {
      type: Array,
      default: () => [],
    },
    options: {
      type: Object,
      required: true,
    },
    globalOptions: {
      type: Object,
      default: () => ({
        autoplay: true,
        controls: false,
        // preload: 'auto',
        fluid: false,
        muted: true,
        controlBar: {
          remainingTimeDisplay: false,
          playToggle: {},
          progressControl: {},
          fullscreenToggle: {},
          volumeMenuButton: {
            inline: false,
            vertical: true,
          },
        },
        notSupportMessage: "无法播放",
        id: "v" + +new Date(),
        techOrder: ["html5", "flvjs", "flash"],
        plugins: {},
      }),
    },
    number: {
      type: String,
      default: "",
    },
    back: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    playType() {
      return this.options.playType || "05";
    },
  },
  data() {
    return {
      player: null,
      playerHidden: false,
      playSrc: "",
      reseted: true,
      loading: false,
      loadingText: "",
      VideoPlayData: {
        startTime: null,
        endTime: "",
        number: this.options.videoNumber || this.number || this.options.number,
      },
      isflowRate: false,
      errorInfo: "",
      timer: null,
    };
  },
  watch: {
    // options: {
    // 	deep: true,
    // 	handler(options, oldOptions) {
    // 		console.log('options change', options)
    // 		this.dispose(() => {
    // 			if (options && options.sources && options.sources.length) {
    // 				this.initialize()
    // 			}
    // 		})
    // 	}
    // },
  },
  created() {
    this.getData();
  },
  mounted() {
    window.addEventListener("beforeunload", this.handleBeforeUnload);
    if (this.initRender) {
      this.render();
    }
    this.updateStatus();
    this.startTimer();
  },
  methods: {
    startTimer() {
      this.timer = setTimeout(() => {
        if (!this.VideoPlayData.startTime) {
          this.updateStatus(3);
        }
      }, 20000);
    },
    // 清除定时器
    clearTimer() {
      clearTimeout(this.timer);
      this.timer = null;
    },
    updateStatus(state = 1) {
      this.$post("/fireFightingIOT/device/updateDeviceState", {
        number: this.VideoPlayData.number,
        state,
      }).then((res) => {
        if (res.code == 0) {
          if (state == 3) {
            this.$message.error("视频无法播放");
          }
        }
      });
    },
    getData() {
      this.$get("/fireFightingIOT/device/getVideoPlayTime", {
        number: this.VideoPlayData.number,
      })
        .then((res) => {
          if (res.code == 0) {
            this.isflowRate = true;
          }
        })
        .catch((err) => {
          this.isflowRate = false;
          this.errorInfo = err.msg;
        });
    },
    handleBeforeUnload() {
      // event.returnValue = '提示用户确认离开';
      if (this.player) {
        this.dispose();
        this.updateVideoPlayTime();
      }
      if (this.playType == "05") {
        this.updateVideoPlayTime();
      }
    },
    updateVideoPlayTime() {
      let date = new Date();
      this.VideoPlayData.endTime = formatDate(
        new Date(date),
        "yyyy-MM-dd hh:mm:ss"
      );
      this.$post("/fireFightingIOT/device/updateVideoPlayTime", {
        ...this.VideoPlayData,
      }).then((res) => {
        if (res.code !== 0) {
          this.$message.error(res.msg);
        }
      });
    },
    onImgLoad() {
      this.loading = false;
      let date = new Date();
      if (!this.VideoPlayData.startTime) {
        this.VideoPlayData.startTime = formatDate(
          new Date(date),
          "yyyy-MM-dd hh:mm:ss"
        );
      }
    },
    initialize() {
      let date = new Date();
      const that = this;
      if (
        !this.options ||
        !this.options.sources ||
        this.options.sources.length == 0
      )
        return;
      // // videojs options
      const videoOptions = Object.assign({}, this.globalOptions, this.options);
      // // let videoEl = this.$el.querySelector('video')
      // // ios fullscreen
      if (this.playsinline) {
        this.$refs.liveVideo.setAttribute("playsinline", this.playsinline);
        this.$refs.liveVideo.setAttribute(
          "webkit-playsinline",
          this.playsinline
        );
        this.$refs.liveVideo.setAttribute("x5-playsinline", this.playsinline);
        this.$refs.liveVideo.setAttribute("x5-video-player-type", "h5");
        this.$refs.liveVideo.setAttribute("x5-video-player-fullscreen", false);
      }
      // // cross origin
      if (this.crossOrigin !== "") {
        this.$refs.liveVideo.crossOrigin = this.crossOrigin;
        this.$refs.liveVideo.setAttribute("crossOrigin", this.crossOrigin);
      }
      // emit event
      const emitPlayerState = (event, value) => {
        if (event) {
          this.$emit(event, this.player);
        }
        if (value) {
          this.$emit(this.customEventName, { [event]: value });
        }
      };
      // avoid error "VIDEOJS: ERROR: Unable to find plugin: __ob__"
      if (videoOptions.plugins) {
        delete videoOptions.plugins.__ob__;
      }
      // // videoOptions
      // // console.log('videoOptions', videoOptions)
      // player
      const self = this;
      if (
        videoOptions.sources[0] &&
        videoOptions.sources[0].type == "video/x-flv"
      ) {
        videoOptions.flvjs = {
          mediaDataSource: {
            isLive: false,
            cors: true,
            withCredentials: false,
          },
        };
      }

      let $video = this.$el.querySelector("video");
      this.player = videojs(
        $video,
        videoOptions,
        function(e) {
          // events
          videojs.log("播放器已经准备好了!");
          // that.loading = true
          // that.loadingText = '开始加载'
          this.on("error", (e) => {
            console.log("error", e);
            that.loading = false;
            that.loadingText = "加载失败";
          });
          this.on("loadstart", (e) => {
            console.log("loadstart", e);
            that.loading = false;
            that.loadingText = "开始加载";
          });
          this.on("progress", (e) => {
            console.log("progress");
            // that.loading = true
            // that.loadingText = '加载中'
          });
          this.on("timeupdate", (e) => {
            // console.log('timeupdate')
          });
          this.on("loadedmetadata", (e) => {
            that.loading = false;
            console.log("loadedmetadata");
          });
          this.on("playing", (e) => {
            if (that.loading) {
              that.loading = false;
            }
            console.log("playing");
          });
          this.on("pause", (e) => {
            that.loading = false;
            console.log("pause");
          });
          this.on("play", (e) => {
            console.log("play");
            if (!that.VideoPlayData.startTime) {
              that.VideoPlayData.startTime = formatDate(
                new Date(date),
                "yyyy-MM-dd hh:mm:ss"
              );
            }
            that.loading = false;
          });
          this.on("waiting", (e) => {
            console.log("waiting");
            that.loading = false;
            // that.loadingText = "等待响应";
          });
          this.on("stalled", (e) => {
            console.log("网速异常");
          });
        },
        (err) => {}
      );
    },
    dispose(callback) {
      if (this.player && this.player.dispose) {
        if (this.player.techName_ !== "Flash") {
          this.player.pause && this.player.pause();
        }
        this.player.dispose();
        if (!this.$el.children.length) {
          const video = document.createElement("video");
          video.className = "video-js";
          if (this.crossOrigin !== "") {
            video.crossOrigin = this.crossOrigin;
            video.setAttribute("crossOrigin", this.crossOrigin);
          }
          this.$el.appendChild(video);
        }
        this.player = null;
        this.$nextTick(() => {
          this.reseted = false;
          this.$nextTick(() => {
            this.reseted = true;
            this.$nextTick(() => {
              callback && callback();
            });
          });
        });
      }
    },
    play() {
      if (this.player) {
        this.player.play();
      }
    },
    pause() {
      if (this.player) {
        this.player.pause();
      }
    },
    render() {
      this.loading = true;
      this.loadingText = "正在加载";
      this.playerHidden = true;
      setTimeout(() => {
        this.playerHidden = false;
        this.$nextTick(() => {
          if (this.options.playType == "05") {
            if (this.player) {
              this.dispose();
            }
            this.playSrc = this.options.sources[0].src;
          } else if (
            this.options &&
            this.options.sources &&
            this.options.sources.length
          ) {
            if (this.player) {
              this.dispose(() => {
                  this.initialize();
              });
            } else {
                this.initialize();
            }
          }
        });
      }, 100);
    },
    closeVideoStream() {
      this.$get("/fireFightingIOT/device/closeVideoStream", {
        number: this.VideoPlayData.number,
      }).then((res) => {
        console.log(res);
      });
    },
  },
  beforeDestroy() {
    if (!this.back) {
      this.clearTimer();
      window.removeEventListener("beforeunload", this.handleBeforeUnload);
      if (this.player) {
        this.dispose();
      }
      if (this.VideoPlayData.startTime) {
        this.updateVideoPlayTime();
      }
      if (this.options.productId == "6017") {
        this.closeVideoStream();
      }
    }
  },
};
</script>
<style lang="less">
.video-js {
  width: 100%;
  height: 100%;
}
.live-warp {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: #000;
  .img {
    max-width: 100%;
    max-height: 100%;
  }
}
.video-status {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 11;
  width: 100%;
  height: 100%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nodata {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: relative;
  background: #000;
}
.update {
  padding: 0 10px;
  margin-left: 10px;
  background: #0f71e2;
  border-radius: 5px;
  color: #fff;
  font-size: 12px;
  position: absolute;
  bottom: 10px;
  right: 10px;
  z-index: 9999;
}
</style> -->
<template>
  <div style="width:100%;height:100%;position:relative;">
    <div class="live-warp" v-if="options.playType == '05'">
      <img
        class="img"
        :id="'imgeVideo' + this.options.number"
        :src="playSrc"
        alt=""
        @load="onImgLoad"
      />
    </div>
    <div ref="videoPlayerBox" class="component" v-else>
      <video class="videoPlayer video-js" muted ></video>
    </div>
    <div class="video-status" v-if="loading">{{ loadingText }}</div>
  </div>
  <!-- <div class="nodata" v-else>{{ errorInfo }}</div> -->
</template>
<script>
import videojs from "video.js";
import "video.js/dist/video-js.min.css";
import "videojs-contrib-hls";
import "videojs-flvjs-es6";
import "videojs-flash";
import { formatDate } from "@/assets/js/utils";
export default {
  // inject: ["updateAction"],
  inject: {
    updateAction: {
      from: "updateAction",
      default: () => ({}),
    },
  },

  props: {
    videoParams: {
      type: Object,
      default: () => ({}),
    },
    options: {
      type: Object,
      default: () => ({}),
    },
    initRender: {
      type: Boolean,
      default: false,
    },
    back: {
      type: Boolean,
      default: false,
    },
    number: {
      // 设备类型
      type: String,
      default: "",
    },
  },
  data() {
    return {
      player: null,
      playerHidden: false,
      playSrc: "",
      reseted: true,
      loading: false,
      loadingText: "",
      VideoPlayData: {
        startTime: null,
        endTime: "",
        number: this.options.videoNumber || this.number || this.options.number,
      },
      isflowRate: false,
      errorInfo: "",
      timer: null,
    };
  },
  created() {
    this.getData();
  },
  mounted() {
    window.addEventListener("beforeunload", this.handleBeforeUnload);
    // if (this.initRender) {
    this.initPlayer();
    // }
    this.updateStatus(1, false);
    this.startTimer();
  },
  beforeDestroy() {
    this.clearTimer();
    if (!this.back) {
      this.disposePlayer();
      if (this.options.productId == "6017"||this.options.productId == "6019") {
        this.closeVideoStream();
      }
      if (!this.VideoPlayData.startTime) {
        this.updateStatus(3, true);
      } else {
        console.log(this.isFunction(this.updateAction));
        if (this.isFunction(this.updateAction)) {
          this.updateAction();
        }
      }
    }
  },
  methods: {
    isFunction(obj) {
      return typeof obj === "function";
    },
    startTimer() {
      this.timer = setTimeout(() => {
        if (!this.VideoPlayData.startTime) {
          this.updateStatus(3, false);
        }
      }, 20000);
    },
    // 清除定时器
    clearTimer() {
      clearTimeout(this.timer);
      this.timer = null;
    },
    updateStatus(state = 1, type) {
      this.$post("/fireFightingIOT/device/updateDeviceState", {
        number: this.VideoPlayData.number,
        state,
      }).then((res) => {
        if (res.code == 0) {
          if (type && this.isFunction(this.updateAction)) {
            this.updateAction();
          }
          if (state == 3 && !type) {
            this.$message.error("视频无法播放");
          }
        }
      });
    },
    getData() {
      this.$get("/fireFightingIOT/device/getVideoPlayTime", {
        number: this.VideoPlayData.number,
      })
        .then((res) => {
          if (res.code == 0) {
            this.isflowRate = true;
          }
        })
        .catch((err) => {
          this.isflowRate = false;
          this.errorInfo = err.msg;
        });
    },
    handleBeforeUnload() {
      // event.returnValue = '提示用户确认离开';
      if (this.player) {
        this.dispose();
        this.updateVideoPlayTime();
      }
      if (this.playType == "05") {
        this.updateVideoPlayTime();
      }
    },
    updateVideoPlayTime() {
      let date = new Date();
      this.VideoPlayData.endTime = formatDate(
        new Date(date),
        "yyyy-MM-dd hh:mm:ss"
      );
      this.$post("/fireFightingIOT/device/updateVideoPlayTime", {
        ...this.VideoPlayData,
      }).then((res) => {
        if (res.code !== 0) {
          this.$message.error(res.msg);
        }
      });
    },
    onImgLoad() {
      this.loading = false;
      let date = new Date();
      if (!this.VideoPlayData.startTime) {
        this.VideoPlayData.startTime = formatDate(
          new Date(date),
          "yyyy-MM-dd hh:mm:ss"
        );
      }
    },
    closeVideoStream() {
      this.$get("/fireFightingIOT/device/closeVideoStream", {
        number: this.VideoPlayData.number,
      }).then((res) => {
        console.log(res);
      });
    },
    // 初始化播放器
    initPlayer() {
      this.$nextTick(() => {
        if (this.options.playType == "05") {
          if (this.player) {
            this.player.dispose();
          }
          this.playSrc = this.options.sources[0].src;
          return;
        }
        let playerOption = {
          preload: "auto", // 预加载
          autoplay: true, // 自动播放
          muted: true,
          hasAudio: false,
          techOrder: ["html5", "flvjs", "flash"], // 这里的顺序一定要 'flvjs' 在 'flash' 前面，要不然 flv 格式的就无法播放了
          // 如果报 app.js:242798 Uncaught TypeError: this.el_.vjs_getProperty is not a function 错误，只保留 'flash' 就不报错了
          // 报错 The "flash" tech is undefined. Skipped browser support check for that tech. 可以查看 videojs-flash 里面 node_modules 查看需要的 video.js 的版本，然后修改video.js的版本就可以了
          flash: {
            hls: { withCredentials: false },
          },
          flvjs: {
            mediaDataSource: {
              cors: true,
              withCredentials: false,
            },
          },
          sources: [
            {
              src: this.options.sources[0].src,
              type: this.options.sources[0].type,
            },
          ],
        };
        let that = this;
        let date = new Date();
        let $video = this.$el.querySelector("video");
        this.player = videojs(
          $video,
          playerOption,
          function(e) {
            videojs.log("播放器已经准备好了!");
            this.on("error", (e) => {
              that.loading = false;
              that.loadingText = "加载失败";
            });
            this.on("loadstart", (e) => {
              that.loading = false;
              that.loadingText = "开始加载";
            });
            this.on("loadedmetadata", (e) => {
              that.loading = false;
            });
            this.on("playing", (e) => {
              if (that.loading) {
                that.loading = false;
              }
            });
            this.on("pause", (e) => {
              that.loading = false;
            });
            this.on("play", (e) => {
              if (!that.VideoPlayData.startTime) {
                that.VideoPlayData.startTime = formatDate(
                  new Date(date),
                  "yyyy-MM-dd hh:mm:ss"
                );
              }
              that.loading = false;
            });
          },
          (err) => {}
        );
      });
    },
    // 重新加载播放器
    loadPlayer() {
      this.$refs.videoPlayerBox.innerHTML = `<video class="videoPlayer video-js"></video>`;
      this.$nextTick(() => {
        this.initPlayer();
      });
    },
    // 销毁播放器
    disposePlayer() {
      if (this.player) {
        this.player.dispose();
      }
    },
    getType(type) {
      let playerType = "";
      switch (type) {
        case "FLV":
          playerType = "video/x-flv";
          break;
        case "HLS":
          playerType = "application/x-mpegURL";
          break;
        case "RTMP":
          playerType = "rtmp/flv";
          break;
        case "RTSP":
          playerType = "video/mp4";
          break;
      }
      return playerType;
    },
  },
};
</script>
<style lang="less">
.video-js {
  width: 100%;
  height: 100%;
}
.component {
  width: 100%;
  height: 100%;
}
.live-warp {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: #000;
  .img {
    max-width: 100%;
    max-height: 100%;
  }
}
.video-status {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 11;
  width: 100%;
  height: 100%;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nodata {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: relative;
  background: #000;
}
.update {
  padding: 0 10px;
  margin-left: 10px;
  background: #0f71e2;
  border-radius: 5px;
  color: #fff;
  font-size: 12px;
  position: absolute;
  bottom: 10px;
  right: 10px;
  z-index: 9999;
}
</style>
